#include "WindowsApplication.hpp"
#include <tchar.h>
#include <BaseApplication.cpp>

using namespace My;

namespace My {
    GfxConfiguration config(8, 8, 8, 8, 32, 0, 0, 960, 540, L"GameEngineFromScratch(Windows)");
    WindowsApplication g_App(config);
    IApplication* g_pApp = &g_App;
}

int My::WindowsApplication::Initialize()
{
    int result;

    result = BaseApplication::Initialize();

    if (result != 0) 
    {
        exit(result);
    }

    // get the HINSTANCE of the Console Program
    HINSTANCE hInstance = GetModuleHandle(NULL);

    // the handle for the window, filled by a function
    HWND hWnd;
    // the struct holds information for the window class
    WNDCLASSEX wc;

    // clear out the window class for use
    ZeroMemory(&wc, sizeof(WNDCLASSEX));

    // fill in the struct with the needed information
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
    wc.lpszClassName = _T("GameEngineFromScratch");

    // register the window class
    RegisterClassEx(&wc);

    // create the window and use the result as the handle
    hWnd = CreateWindowEx(0,
                          ("GameEngineFromScratch"),   // name of the window
                          m_Config.appName,     // title of the window
                          WS_OVERLAPPEDWINDOW,  // window style
                          CW_USEDEFAULT,        // x positon of the window    
                          CW_USEDEFAULT,        // y positon of the window
                          m_Config.screenWidth, // width of the window
                          m_Config.screenHeight,// height of the window
                          NULL,                 // we have no parent window, NULL
                          NULL,                 // we aren't using menus, null
                          hInstance,            // application handle
                          NULL);                // used with multiple windows, NULL
    
    // display the window on the screen
    ShowWindow(hWnd, nCmdShow); 

    return result;
}

void My::WindowsApplication::Finalize()
{

}

void My::WindowsApplication::Tick()
{
    // the struct holds Windows event messages
    MSG msg;

    // wait for the next message in the queue, store the result in "msg"
    while(PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
        // translate keystroke messages into the right format
        TranslateMessage(&msg);

        // send the message to the WindowProc function
        DispatchMessage(&msg);
    }
}


LRESULT CALLBACK My::WindowsApplication::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_CREATE:
            break;
        // this message is read when the window is closed
        case WM_DESTROY:
            {
                PostQuitMessage(0);
                m_bQuit = true;
                return 0;
            }
    }

    return DefWindowProc(hWnd, message, wParam, lParam);
}